package com.david.func_test

//import com.bytedance.sdk.open.aweme.authorize.model.Authorization
//import com.bytedance.sdk.open.douyin.DouYinOpenApiFactory
//import com.bytedance.sdk.open.douyin.DouYinOpenConfig

import android.Manifest
import android.animation.Animator
import android.animation.LayoutTransition
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.annotation.TargetApi
import android.app.AlarmManager
import android.app.AlertDialog
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_IMMUTABLE
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Resources
import android.database.Cursor
import android.graphics.*
import android.graphics.drawable.GradientDrawable
import android.media.MediaCodecList
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.Uri
import android.os.*
import android.provider.Settings
import android.text.Html
import android.util.Log
import android.util.TypedValue
import android.view.*
import android.view.animation.*
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.MediaController
import android.widget.TextView
import android.widget.Toast
import android.widget.VideoView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.animation.doOnEnd
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.core.view.marginBottom
import androidx.core.view.updateLayoutParams
import androidx.customview.widget.ViewDragHelper.STATE_IDLE
import androidx.customview.widget.ViewDragHelper.STATE_SETTLING
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.work.Constraints
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import com.airbnb.lottie.LottieAnimationView
import com.airbnb.lottie.LottieDrawable
import com.alibaba.fastjson.JSON
import com.david.core.utils.StateListDrawableHelper.context
import com.david.func_test.retrofitinterface.testInterface
import com.david.func_test.retrofitinterface.testInterface1
import com.david.func_test.util.AnimUtil
import com.david.func_test.util.ImFileUtil
import com.david.func_test.util.OnFileCopiedListener
import com.david.func_test.util.TestUtil
import com.david.func_test.view.AlbumCarChoosePop
import com.david.func_test.view.FloatIconView
import com.david.func_test.view.LabelBean
import com.david.func_test.view.LabelsView
import com.david.func_test.view.LimitLengthTextView
import com.david.func_test.worker.DailyWorker
import com.david.http.http.method.test.methodTestInterface
import com.david.http.http.method.test1.methodTest1Interface
import com.david.http.http.util.request
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.config.SelectModeConfig
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnPermissionsInterceptListener
import com.luck.picture.lib.interfaces.OnRequestPermissionListener
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.luck.picture.lib.language.LanguageConfig
import com.permissionx.guolindev.PermissionX
import com.youth.banner.util.BannerUtils.dp2px
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.*
import java.net.URL
import java.util.*
import java.util.concurrent.TimeUnit


class MainActivity : AppCompatActivity() {
    private lateinit var btn: TextView
    override fun onCreate(savedInstanceState: Bundle?) {
        lifecycle.addObserver(LifecycleObserverTest())

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        btn = findViewById(R.id.click_view)


        //if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) {
        //    requestAllFilePermission(this, {
        //
        //    })
        //}
        btn.setOnClickListener {
            //com.heytap.book/com.qq.reader.activity.MainActivity
            //val intent = Intent(Intent.ACTION_VIEW, Uri.parse("book://"))
            //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            //startActivity(intent)




            //startActivity(Intent(this, FlowTestActivity::class.java))
//            testImgAlpha()
//            showHideViewWidthAnim()
//            testDialog(it)
//            testGradient()
//            testShapeDrawable(it)
//            testText()
//            testVibrate()
//            testStep()
//            getParam()
//            startActivity(Intent(this, StepActivity::class.java))
//            testDouyin()
//            testDialogPosition()
//            testPoster()
//            testToast()
//            testSysShare()
//            Log.e("alarm", "view clicked...")

//            lottieView.drawable?.bounds?.toString()?.let { it1 -> Log.e("rect", it1) }

//            testFlutter()
//            testFlutterFragment()
//            startActivity(Intent(this, AnimTestActivity::class.java))
//            startActivity(Intent(this, ScrollerTestActivity::class.java))
//            startActivity(Intent(this, ViewPagerTestActivity::class.java))
//            startActivity(Intent(this, RecyclerTestActivity::class.java))
//            startActivity(Intent(this, MdnsTestActivity::class.java))
//            startActivity(Intent(this, TabTestActivity::class.java))
//            startActivity(Intent(this, SlideDeleteTestActivity::class.java))

//            DiscoverFloatShopFilterPop(this@MainActivity).show()

//            findViewById<ImageView>(R.id.test).setColorFilter(Color.GREEN)
//            testAnim()

//            findViewById<TextView>(R.id.click_view).text = Html.fromHtml("这个<font color='#ff0000'><big>大</big></font>字<font color='#0000ff'>颜色</font>很好看",
//                Html.FROM_HTML_MODE_LEGACY)

//            findViewById<TextView>(R.id.click_view).text = Html.fromHtml("<big>快 <b>8</b>/</big>14  <big>慢 <b>4</b>/</big>6",
//                Html.FROM_HTML_MODE_LEGACY)

//            callPhone()
//            Log.e("height", "btn height:" + btn.height)
//            Log.e("height", "50 height:" + dp2px(200f))
//            Log.e("height", "50 height:" + 200.dp)
//            showMask()

//            testLottie()

//            testRichText()

//            testValueAnimator()
//            testScreenInfo()

//            getBottomNavBarHeight()

//            startActivity(Intent(this, SnapHelperActivity::class.java))
//            startActivity(Intent(this, AnimIntercepterActivity::class.java))

//            testHwInstallInfo()

//            testLifecycleScope()
//            chooseFile()
//            QuitTeamDialog(this, "test") { }.show()
//            downloadFile()
//            startActivity(Intent(this, LottieAnimTestActivity::class.java))
//            Log.e("encod", "support hevc:${isH265DecoderSupport()}")
//            testTimeFormat()
//            testDotAnim()
//            testProfile()
//            Log.e("main", "test is $test")
//            testIconShowHide()
//            startActivity(Intent(this, SpanableTestActivity::class.java))

            //testRetrofit()

            //systemShare()
            //startActivity(Intent(this, CompassActivity::class.java))
            //permissionX()
//            startActivity(Intent(this, LeakTestActivity::class.java))

        }

        findViewById<View>(R.id.img_cloud_left).setOnClickListener {
            testPopup(it)
        }
//        testLabels()
        testMyTab()
        testMyDots()

        initHomeTabBehavior()

        ImFileUtil.init(applicationContext)

        findViewById<TextView>(R.id.click_view)?.let {
            it.post {
                Log.e("line", "${it.getLayout().getEllipsisCount(1)}")
        }
        }


        val androidId: String = Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID)
        Log.d("Android", "Android ID : $androidId")




        findViewById<VideoView>(R.id.video_view)?.let{
            it.setVideoURI(Uri.parse("http://10.114.38.226:8090/files/zeekrvideo2od_vp9.webm"))
            it.start()

            it.setMediaController(MediaController(this));

        }

    }


    //private val toastBinding: VehicleToastKeyPhoneCommonBinding by inflate()
    //private val customToast: Toast by lazy {
    //    Toast(this).apply {
    //        setGravity(Gravity.CENTER, 0, 0)
    //        duration = Toast.LENGTH_SHORT
    //        view = toastBinding.root
    //    }
    //}
    //fun testToast() {
    //
    //}

    /**
     * 使用系统api分享文本/图片，参考链接：https://developer.android.google.cn/training/sharing?hl=zh-cn
     */
    fun systemShare(){
        systemShareText()
        //动态申请获取访问 读写磁盘的权限
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S_V2) {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE), 101);
            } else {
                selectPicShare()
            }
        } else {
            selectPicShare()
        }
    }

    private fun systemShareText() {
        val shareIntent = Intent(Intent.ACTION_SEND)
        shareIntent.type = "text/plain"
        shareIntent.putExtra(Intent.EXTRA_TEXT, "Check out this cool website: https://www.example.com")
        shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject of the message")

        startActivity(Intent.createChooser(shareIntent, "Share link via"))
    }

    private fun systemShareFile(uri: Uri?) {
        val share = Intent.createChooser(Intent().apply {
            action = Intent.ACTION_SEND
            //type = "image/*"
            type = "*/*"
            putExtra(Intent.EXTRA_TEXT, "text。。。")

            // (Optional) Here you're setting the title of the content
            putExtra(Intent.EXTRA_TITLE, "Introducing content previews")

            // (Optional) Here you're passing a content URI to an image to be displayed
            //data = contentUri
            flags = Intent.FLAG_GRANT_READ_URI_PERMISSION

            putExtra(Intent.EXTRA_STREAM, uri)

        }, null)
        startActivity(share)
    }

    private val permissionInterceptor = object : OnPermissionsInterceptListener {
        override fun requestPermission(
            fragment: Fragment?,
            permissionArray: Array<out String>?,
            call: OnRequestPermissionListener?,
        ) {

        }

        override fun hasPermissions(
            fragment: Fragment?,
            permissionArray: Array<out String>?,
        ): Boolean {
            return permissionArray?.getOrNull(0) != Manifest.permission.CAMERA
        }

    }
    private fun selectPicShare() {
        PictureSelector.create(this)
            .openGallery(SelectMimeType.ofImage())
            //.setSelectorUIStyle(getWeChartSelectorStyle(context))
            .setLanguage(LanguageConfig.UNKNOWN_LANGUAGE)
            //.setImageEngine(GlideEngine.createGlideEngine())
            .setMaxSelectNum(1)
            .setMinSelectNum(1)// 最小选择数量
            .setImageSpanCount(3)// 每行显示个数
            .isEmptyResultReturn(false)// 未选择数据时点击按钮是否可以返回
            .setSelectionMode(SelectModeConfig.SINGLE)//多选还是单选
            .isPageStrategy(true)//分页模式
            .isOriginalControl(true)//是否开启原图功能
            .isDisplayCamera(true)//是否显示相机入口
            .isOpenClickSound(true)//是否开启点击声音
            .isFastSlidingSelect(true)//快速滑动选择
            .isPreviewFullScreenMode(true)//预览点击全屏效果
            .isPreviewZoomEffect(true)//预览缩放效果
            .isPreviewImage(true)
            .setImageEngine(GlideEngine.createGlideEngine())
            .isMaxSelectEnabledMask(true)//达到最大选择数是否开启禁选蒙层
            .isDirectReturnSingle(false)//单选时是否立即返回
            //            .setRecyclerAnimationMode(AnimationType.ALPHA_IN_ANIMATION)//相册列表动画效果
            //.setSelectedData(config.data)// 传入已选图片
            //.setCropEngine(if (config.isCrop) ImageFileCropEngine() else null)//设置相册裁剪引擎
            //.setCompressEngine(true)//设置相册压缩引擎
            //.isGif(showGif ?: false)
            .setPermissionsInterceptListener(permissionInterceptor)
            .forResult(object : OnResultCallbackListener<LocalMedia> {
                override fun onResult(result: ArrayList<LocalMedia>?) {
                    val share = Intent.createChooser(Intent().apply {
                        action = Intent.ACTION_SEND
                        type = "image/*"
                        putExtra(Intent.EXTRA_TEXT, "text。。。")

                        // (Optional) Here you're setting the title of the content
                        putExtra(Intent.EXTRA_TITLE, "Introducing content previews")

                        // (Optional) Here you're passing a content URI to an image to be displayed
                        //data = contentUri
                        flags = Intent.FLAG_GRANT_READ_URI_PERMISSION

                        putExtra(Intent.EXTRA_STREAM, Uri.parse(result?.get(0)?.path))

                    }, null)
                    startActivity(share)
                }

                override fun onCancel() {
                }
            })
    }

    fun bitmap2Bytes(bitmap: Bitmap): ByteArray {
        // 创建一个ByteArrayOutputStream对象
        val byteArrayOutputStream = ByteArrayOutputStream();

        // 将Bitmap压缩为JPEG格式的二进制数据，并写入ByteArrayOutputStream
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);

        // 获取转换后的二进制数据流
        return byteArrayOutputStream.toByteArray();

        // 现在，bitmapData就是Bitmap的二进制数据流

    }

    /**
     * 参考链接：https://guolin.blog.csdn.net/article/details/127024559
     */
    fun permissionX(){
        PermissionX.init(this)
            .permissions(Manifest.permission.READ_CONTACTS, Manifest.permission.CAMERA, Manifest.permission.CALL_PHONE)
            .request { allGranted, grantedList, deniedList ->
                if (allGranted) {
                    Toast.makeText(this, "All permissions are granted", Toast.LENGTH_LONG).show()
                } else {
                    Toast.makeText(this, "These permissions are denied: $deniedList", Toast.LENGTH_LONG).show()
                }
            }
    }

    fun testHideAnim() {
        val view = findViewById<View>(R.id.test_view)
        if (view.marginBottom == -100.dp) {
            AnimUtil.animBottomMargin(view, 0, false, 300)
        } else {
            AnimUtil.animBottomMargin(view, -100.dp, false, 300)
        }
    }


    fun testRetrofit(){
//        https://divaid.github.io/resources/json/books.json
//        retrofitHelper.getRetrofit("https://divaid.github.io/").create(ITestInterface::class.java).testHttp().observe(this) {
//            Log.e("retrofit", it)
//        }

        //http://192.168.1.105:8080/testRetrofit
//        retrofitHelper.create(ITestInterface::class.java).testLocalHttp().observe(this) {
//            Log.e("retrofit", it.data?.name ?: "resutl ...")
//        }


        testInterface1.testRetrofit().request(this) {
            Log.e("retrofit", "testRetrofit:${JSON.toJSONString(it)}")
        }

        testInterface.getNewsList().request(this) {
            Log.e("retrofit", "getNewsList:${JSON.toJSONString(it)}")
        }
        methodTestInterface.test().request(this) {
            Log.e("retrofit", "test:${JSON.toJSONString(it)}")
        }

        methodTest1Interface.testArr().request(this) {
            Log.e("retrofit", "testArr:${JSON.toJSONString(it)}")
        }
    }


    private var iconView: FloatIconView? = null
    fun testIconShowHide() {
        if (iconView == null) {
            iconView = FloatIconView(findViewById(R.id.icon_parent), this)
            iconView?.checkShow(findViewById(R.id.behavior_list))
        }

//        findViewById<RecyclerView>(R.id.behavior_list).addOnScrollListener(object :
//            RecyclerView.OnScrollListener() {
//            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
//                super.onScrollStateChanged(recyclerView, newState)
//                iconView?.removeCallbacks(showTask)
//                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
//                    iconView?.postDelayed(showTask, 300)
//                } else {
//                    iconView?.hide()
//                }
//            }
//        })
//        iconView?.show()
    }

    var test = 0
    get() {
        if (field == 0) {
            testSetGet()
        }
        return field
    }
    private fun testSetGet() {
        test = 1
    }

    //profile中的arrange by app可查分配了哪些对象，arrange by callstack可查看由哪个方法分配的对象
    private fun testProfile() {
        for (index in 0 .. 1000) {
            val s = String(charArrayOf('a', 'b', 'c'))
        }
    }


    private fun testDotAnim() {
        for (index in 0 until dotList.childCount) {
            val view = dotList.getChildAt(index)
            if (view.left < resources.displayMetrics.widthPixels) {
                dotList.getChildAt(index).startAnimation(getDotAnim(400f + index * 300))
                Log.e("dot", "anim...")
            }
        }
    }

    private fun getDotAnim(startX: Float): TranslateAnimation {
        val anim = TranslateAnimation(startX, 0f, 0f, 0f)
        anim.duration = 500
        anim.interpolator = DecelerateInterpolator()
        return anim
    }

    var pop: AlbumCarChoosePop? = null
    private fun testPopup(view: View){
        if (pop == null) {
            pop = AlbumCarChoosePop(view, this)
        }
        if (pop?.isShowing != true) {
            pop?.showAsDropDown(view)
        }
    }



    private val clickListener: View.OnClickListener = object :View.OnClickListener{
        override fun onClick(v: View?) {
            val tempRv = v?.parent as RecyclerView
            val distance = v.left - (((v.parent as View).width shr 1) - (v.width shr 1))
            if (distance > 0) {
                if (!tempRv.canScrollHorizontally(1)) {
                    return
                }
            } else if (distance < 0) {
                if (!tempRv.canScrollHorizontally(-1)) {
                    return
                }
            }
            tempRv.smoothScrollBy(
                v.left - (((v.parent as View).width shr 1) - (v.width shr 1)),
                0
            )
        }
    }


    private lateinit var rv: RecyclerView
    private fun testMyTab(){
        rv = findViewById(R.id.my_tab)
        rv.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
        rv.adapter = AlbumTabAdapter(rv)
    }

    class AlbumTabAdapter(var recyclerView: RecyclerView): RecyclerView.Adapter<AlbumTabHolder>() {
        private var valueAnim = ValueAnimator.ofFloat(0f, 1f)
        private val selectColor = Color.parseColor("#242b29")
        private val normalColor = Color.parseColor("#8E9496")
        private val rColorDis = 0x8E - 0x24
        private val gColorDis = 0x94 - 0x2b
        private val bColorDis = 0x96 - 0x29
        private val selectSize = 21f
        private val normalSize = 15f

        private val textRestWidth = dp2px(33f)

        private val tabBeans = ArrayList<MyTabBean>()

        private val measurePaint = Paint()
        init {
            measurePaint.textSize = 15f
            measurePaint.strokeWidth = 0.5f
            measurePaint.style = Paint.Style.FILL_AND_STROKE

            tabBeans.add(MyTabBean("外观", "1"))
            tabBeans.add(MyTabBean("内饰", "1"))
            tabBeans.add(MyTabBean("细节", "1"))
            tabBeans.add(MyTabBean("Lifestyle", "1"))
        }

        private var onClickListener = View.OnClickListener {
            val position = it.tag as Int
            if (position == lastSelectPosition) {
                return@OnClickListener
            }

            (it as TextView)

            moveToCenter(it)

            targetView = it

            setAnim()
            valueAnim.start()

            lastSelectPosition = it.tag as Int
        }

        private fun setAnim(){
            valueAnim = ValueAnimator.ofFloat(0f, 1f)
            valueAnim.duration = 200
            valueAnim.addUpdateListener {
                val progress = it.animatedValue as Float
                lastSelectView?.textSize = selectSize - (progress * 6)
                targetView?.textSize = normalSize + progress * 6


                val tr = (0x8E - progress * rColorDis).toInt()
                val tg = (0x94 - progress * gColorDis).toInt()
                val tb = (0x96 - progress * bColorDis).toInt()
                val tColor = ((0xFF shl 24) or (tr shl 16) or (tg shl 8) or tb)
                targetView?.setTextColor(tColor)

                targetView?.paint?.strokeWidth = progress + 0.4f

                val lr = (0x24 + progress * rColorDis).toInt()
                val lg = (0x2b + progress * gColorDis).toInt()
                val lb = (0x29 + progress * bColorDis).toInt()
                val lColor = ((0xFF shl 24) or (lr shl 16) or (lg shl 8) or lb)
                lastSelectView?.setTextColor(lColor)
                lastSelectView?.paint?.strokeWidth = (1 - progress) + 0.4f
            }

            valueAnim.doOnEnd {
                lastSelectView = targetView
                targetView = null
            }
        }

        private var lastSelectView: TextView? = null
        private var targetView: TextView? = null
        private var lastSelectPosition = 0
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlbumTabHolder {
            val title = TextView(parent.context)
            title.layoutParams = ViewGroup.LayoutParams(150, ViewGroup.LayoutParams.MATCH_PARENT)
            title.gravity = Gravity.CENTER
            title.setOnClickListener(onClickListener)
            title.setTextColor(Color.parseColor("#8E9496"))
            title.paint?.style = Paint.Style.FILL_AND_STROKE
            return AlbumTabHolder(title)
        }

        override fun onBindViewHolder(holder: AlbumTabHolder, position: Int) {
            holder.item.textSize = normalSize
            holder.item.paint.strokeWidth = 0.4f
            holder.item.layoutParams.width = (holder.item.paint.measureText(tabBeans[position].name) + textRestWidth).toInt()

            if (lastSelectPosition == position) {
                holder.item.textSize = selectSize
                lastSelectView = holder.item
                holder.item.setTextColor(selectColor)
                holder.item.paint.strokeWidth = 1.4f
            } else {
                holder.item.setTextColor(normalColor)
            }
            holder.item.text = tabBeans[position].name
            holder.item.tag = position
        }

        override fun getItemCount(): Int {
            return tabBeans.size
        }

        private fun moveToCenter(item: View){
            val distance = item.left - (((item.parent as View).width shr 1) - (item.width shr 1))
            if (distance > 0) {
                if (!recyclerView.canScrollHorizontally(1)) {
                    return
                }
            } else if (distance < 0) {
                if (!recyclerView.canScrollHorizontally(-1)) {
                    return
                }
            }
            recyclerView.smoothScrollBy(
                item.left - (((item.parent as View).width shr 1) - (item.width shr 1)),
                0
            )
        }

        data class MyTabBean(var name: String, var id: String?)
    }

    class AlbumTabHolder(var item: TextView): RecyclerView.ViewHolder(item)


    private lateinit var dotList: RecyclerView
    private fun testMyDots(){
        dotList = findViewById(R.id.my_dots)
        dotList.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
        dotList.adapter = AlbumDotAdapter(dotList)
        dotList.post {
            testDotAnim()
        }
    }

    class AlbumDotAdapter(var recyclerView: RecyclerView): RecyclerView.Adapter<AlbumDotHolder>() {
        private var valueAnim = ValueAnimator.ofFloat(0f, 1f)

        private var lastSelectView: FrameLayout? = null
        private var targetView: FrameLayout? = null
        private var lastSelectPosition = 0
        private val normalWidth = dp2px(33f)
        private val selectWidth = dp2px(36f)
        private val sizeMinus = selectWidth - normalWidth
        private var dotNormalParam = FrameLayout.LayoutParams(normalWidth, normalWidth)
        private var dotSelectParam = FrameLayout.LayoutParams(selectWidth, selectWidth)
        init {
            dotNormalParam.gravity = Gravity.CENTER
            dotSelectParam.gravity = Gravity.CENTER
        }

        private var onClickListener = View.OnClickListener {
            val position = it.tag as Int
            if (position == lastSelectPosition) {
                return@OnClickListener
            }

            moveToCenter(it)

            targetView = it as FrameLayout?

            setAnim()
            valueAnim.start()

            lastSelectPosition = it.tag as Int
        }

        private fun setAnim(){
            valueAnim = ValueAnimator.ofFloat(0f, 1f)
            valueAnim.duration = 200
            valueAnim.addUpdateListener {
                val progress = it.animatedValue as Float
                val toNormalParam = FrameLayout.LayoutParams((selectWidth - progress * sizeMinus).toInt(), (selectWidth - progress * sizeMinus).toInt())
                toNormalParam.gravity = Gravity.CENTER
                val toSelectParam = FrameLayout.LayoutParams((normalWidth + progress * sizeMinus).toInt(), (normalWidth + progress * sizeMinus).toInt())
                toSelectParam.gravity = Gravity.CENTER
                lastSelectView?.getChildAt(0)?.layoutParams = toNormalParam
                targetView?.getChildAt(0)?.layoutParams = toSelectParam

                lastSelectView?.getChildAt(0)?.background?.alpha = (255 * (1 - progress)).toInt()
                targetView?.getChildAt(0)?.background?.alpha = (255 * progress).toInt()
            }

            valueAnim.doOnEnd {
                lastSelectView = targetView
                targetView = null
            }
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlbumDotHolder {
            val dotParent = FrameLayout(parent.context)
            dotParent.layoutParams = ViewGroup.MarginLayoutParams(dp2px(52f), dp2px(52f))

            val dot = ImageView(parent.context)
            dot.setPadding(dp2px(6f), dp2px(6f), dp2px(6f), dp2px(6f))
//            val drawable = GradientDrawable()
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
//                drawable.setColors(intArrayOf(Color.parseColor("#F2F3F5"), Color.WHITE), FloatArray(0))
//            }
//            drawable.shape = GradientDrawable.OVAL
//            drawable.gradientType = GradientDrawable.RADIAL_GRADIENT
//            drawable.alpha = 0
//            drawable.gradientRadius = 80f

            val drawable = parent.context.getDrawable(R.drawable.dot_bg) as GradientDrawable
//            drawable.gradientRadius = normalWidth.toFloat()
            dot.background = drawable

            val param = FrameLayout.LayoutParams(normalWidth, normalWidth)
            param.gravity = Gravity.CENTER
            dot.layoutParams = param


            dotParent.setOnClickListener(onClickListener)
            dotParent.addView(dot)
            return AlbumDotHolder(dotParent, dot)
        }

        override fun onBindViewHolder(holder: AlbumDotHolder, position: Int) {
            if (position % 2== 0) {
                holder.dot.setImageResource(R.mipmap.dot1)
            } else {
                holder.dot.setImageResource(R.mipmap.dot2)
            }

            if (lastSelectPosition == position) {
                lastSelectView = holder.parent
                holder.dot.layoutParams = dotSelectParam
                holder.dot.background.alpha = 255
            } else {
                holder.dot.layoutParams = dotNormalParam
                holder.dot.background.alpha = 0
            }
            holder.parent.tag = position
        }

        override fun getItemCount(): Int {
            return 20
        }

        private fun moveToCenter(item: View){
            val distance = item.left - (((item.parent as View).width shr 1) - (item.width shr 1))
            if (distance > 0) {
                if (!recyclerView.canScrollHorizontally(1)) {
                    return
                }
            } else if (distance < 0) {
                if (!recyclerView.canScrollHorizontally(-1)) {
                    return
                }
            }
            recyclerView.smoothScrollBy(
                item.left - (((item.parent as View).width shr 1) - (item.width shr 1)),
                0
            )
        }

    }

    class AlbumDotHolder(var parent: FrameLayout, var dot: ImageView): RecyclerView.ViewHolder(parent)

    private fun testTimeFormat(){
        var todayCalendar = Calendar.getInstance()
        var durationCalendar = Calendar.getInstance()
        durationCalendar.timeInMillis = 1653235199000

        val todayDayMill = todayCalendar.timeInMillis - todayCalendar.get(Calendar.HOUR_OF_DAY) * 3600000 - todayCalendar.get(Calendar.MINUTE) * 60000 - todayCalendar.get(Calendar.SECOND) * 1000 - todayCalendar.get(Calendar.MILLISECOND)
        val durationDayMill = durationCalendar.timeInMillis - durationCalendar.get(Calendar.HOUR_OF_DAY) * 3600000 - durationCalendar.get(Calendar.MINUTE) * 60000 - durationCalendar.get(Calendar.SECOND) * 1000 - durationCalendar.get(Calendar.MILLISECOND)
        val result = todayDayMill - durationDayMill
        Log.e("time", "result:${result}")
        when {
            result < 86400000 -> {//一天之内
                Log.e("time", "一天之内")
            }
            result < 172800000 -> {//昨天
                Log.e("time", "昨天")
            }
            result < 259200000 -> {//前天
                Log.e("time", "前天")
            }
            result < 345600000 -> {//四天之内
                Log.e("time", "四天内")
            }
            result < 432000000 -> {//五天之内
                Log.e("time", "五天之内")
            }

            result < 518400000 -> {//六天之内
                Log.e("time", "六天之内")
            }

            result < 604800000 -> {//七天之内
                Log.e("time", "七天之内")
            }
//            result < 2.592E9 -> {//三十天之内
//                Log.e("time", "三十天之内")
//            }
//            result < 3.1536E10 -> {//三百六十五天之内
//                Log.e("time", "三百六十五天之内")
//            }
//            else -> {//一年之外
//                Log.e("time", "一年之外")
//            }
            todayCalendar.get(Calendar.YEAR) == durationCalendar.get(Calendar.YEAR) -> {//同一年
                Log.e("time", "同一年")
            }
            else -> {//不同年
                Log.e("time", "不同年")
//                "${targetCalendar.get(Calendar.YEAR)}年${targetCalendar.get(Calendar.MONTH) + 1}月${targetCalendar.get(Calendar.DAY_OF_MONTH)}日"
            }
        }
    }

    /**
     * 检测是否支持H265硬解码
     * @return 检测结果
     */
    public fun isH265DecoderSupport():Boolean{
        val count = MediaCodecList.getCodecCount();
        for(i in 0..count){
            val info = MediaCodecList.getCodecInfoAt(i);
            val name = info.getName();
            if(name.contains("decoder") && name.contains("hevc")){
                return true;
            }
        }
        return false;
    }


    private val chooseFileContracts = registerForActivityResult(ActivityResultContracts.GetContent()){
        systemShareFile(it)
        it?.let { it1 ->
            ImFileUtil.copyFileToCache(applicationContext, it1, object : OnFileCopiedListener {
                override fun onFileCopy(name: String, path: String) {
                    Log.e("main", "name: $name path: $path")
                }

                override fun onCopyFailed(path: String, msg: String) {
                    Log.e("main", "path: $path msg: $msg")
                }
            })
        }
    }
    private fun chooseFile(){
        chooseFileContracts.launch("*/*")
    }

    var handler = object :Handler(Looper.myLooper()!!){
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            Log.e("main", "running...")
            sendEmptyMessageDelayed(0, 1000)
        }
    }
    private fun testLifecycleScope(){
        lifecycleScope.launchWhenResumed {
//            handler.sendEmptyMessageDelayed(0, 1000)

//            flow<Int>{
////                emit(0)
////                Thread.sleep(1000)
////                emit(0)
////                Thread.sleep(1000)
////                emit(0)
////                Thread.sleep(1000)
////                emit(0)
////                Thread.sleep(1000)
////                emit(0)
////                Thread.sleep(1000)
////                Thread.sleep(5000)
//                TestUtil.test()
//                emit(0)
//            }.flowOn(Dispatchers.IO).collect {
//                Log.e("main", "running...")
//            }

            TestUtil.test().collect { result ->
                Log.e("main", "result is $result")
                test()
            }
        }
    }

    private fun downloadFile(){
        CoroutineScope(Dispatchers.IO).launch {
            val file = File(cacheDir, "data.json")
            if (!file.exists()) {
                file.createNewFile()
            }
            try {
                Log.e("time", "start time :${System.currentTimeMillis()}")
                val url= URL("https://www.baidu.com/native-cache/data.json.zip")
                val connect=url.openConnection()
                val input=connect.getInputStream()
                val br = BufferedReader(InputStreamReader(input));
                var line:String?

                val writer = BufferedWriter(FileWriter(file))

//                val sb = StringBuffer()
                line = br.readLine()
                while (line != null) {
//                    sb.append(line)
                    writer.write(line)
                    line = br.readLine()
                }
                writer.close()

                Log.e("time", "end time :${System.currentTimeMillis()}")
//                Log.e("down", sb.toString())
//            return sb.toString()
            } catch ( e:Exception) {
                e.printStackTrace()
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
    }

    //获取华为手机应用安装信息（是否从广告处下载等信息）：https://developer.huawei.com/consumer/cn/doc/distribution/promotion/bp-functions-intelligent-subcontract-attribution-0000001285288280
    private fun testHwInstallInfo(){
        HwInstallInfoUtil.getTrackId(this, "com.david.func_test")
    }

    inner class MyHolder(itemView:View): RecyclerView.ViewHolder(itemView)

    private lateinit var homeTabBehavior: BottomSheetBehavior<View>

    private var isClickChange = false

    private fun initHomeTabBehavior(){
        findViewById<View>(R.id.nav_top).setOnClickListener {
            Log.e("state", "click ${homeTabBehavior.state}")
            isClickChange = true
            if (homeTabBehavior.state == BottomSheetBehavior.STATE_COLLAPSED) {
                homeTabBehavior.isHideable = false
                homeTabBehavior.state = BottomSheetBehavior.STATE_HALF_EXPANDED
            } else {
                homeTabBehavior.isHideable = true
                homeTabBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
            }
        }
        val recycler = findViewById<RecyclerView>(R.id.behavior_list)
        recycler.layoutManager = LinearLayoutManager(this)
        recycler.adapter = object: RecyclerView.Adapter<MyHolder>() {
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
                if (viewType == 0) {
                    val title = TextView(parent.context)
                    title.text = "hahah"
                    title.setPadding(0, 30, 0 ,30)
                    return MyHolder(title)
                } else {
                    return MyHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_pagerviewgroup, parent, false))
                }
            }

            override fun onBindViewHolder(holder: MyHolder, position: Int) {

            }

            override fun getItemCount(): Int {
                return 150
            }

            override fun getItemViewType(position: Int): Int {
                return if (position % 5 == 0) {
                    1
                } else {
                    0
                }
            }

        }

        val view = findViewById<View>(R.id.bottom_tab_sheet)
        homeTabBehavior = BottomSheetBehavior.from(view)
        homeTabBehavior.state = BottomSheetBehavior.STATE_HALF_EXPANDED
        homeTabBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
            private var lastSlide = 0f
            private var lastState = BottomSheetBehavior.STATE_HALF_EXPANDED
            private var curHeight = 0
            override fun onStateChanged(bottomSheet: View, newState: Int) {
//                if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
//                    binding.mapView.cardCallHide()
//                }


                if (STATE_SETTLING == newState) {
                    if (isClickChange) {
                        return
                    }

                    if ((lastState == BottomSheetBehavior.STATE_COLLAPSED )
                    ) {
                        if (lastSlide > 0.1) {
                            homeTabBehavior.state = BottomSheetBehavior.STATE_HALF_EXPANDED
                            lastState = BottomSheetBehavior.STATE_HALF_EXPANDED
                        } else {
                            homeTabBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
                            lastState = BottomSheetBehavior.STATE_COLLAPSED
                        }
                    } else if (lastState == BottomSheetBehavior.STATE_HALF_EXPANDED) {
                        if (lastSlide > 0.55) {
                            homeTabBehavior.state = BottomSheetBehavior.STATE_EXPANDED
                            lastState = BottomSheetBehavior.STATE_EXPANDED
                        } else if (lastSlide < 0.45) {
                            homeTabBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
                            lastState = BottomSheetBehavior.STATE_COLLAPSED
                        }
                    } else if (lastState == BottomSheetBehavior.STATE_EXPANDED) {
                        if (lastSlide < 0.9) {
                            homeTabBehavior.state = BottomSheetBehavior.STATE_HALF_EXPANDED
                            lastState = BottomSheetBehavior.STATE_HALF_EXPANDED
                        } else {
                            homeTabBehavior.state = BottomSheetBehavior.STATE_EXPANDED
                            lastState = BottomSheetBehavior.STATE_EXPANDED
                        }
                    }
                }
                if (newState == STATE_IDLE) {
                    isClickChange = false
                }
                Log.e("state", "newState is $newState")
            }

            override fun onSlide(bottomSheet: View, slideOffset: Float) {
                lastSlide = slideOffset
                Log.e("slide", "$slideOffset")
                //处理右下角按钮偏移量
                if (slideOffset > 0f) {
//                    var behaviorShowHeight = if (lastSlide - slideOffset > 0) {
//                        bottomSheet.height - bottomSheet.height * (1 - slideOffset)
//                    } else {
//                        bottomSheet.height * slideOffset
//                    }.toInt()
//                    if (mViewModel.bizType == TabItemEnum.TAB0.tabType) {
//                        val minHeight = floatHomeWidget?.topMargin.ifInt() + floatHomeWidget?.maxHeight.ifInt() - floatHomeWidget?.param?.topMargin.ifInt()
//                        if (behaviorShowHeight < minHeight) {
//                            behaviorShowHeight = minHeight
//                        }
//                    } else {
//                        val minHeight = floatWidget?.topMargin.ifInt() + floatWidget?.maxHeight.ifInt() - floatWidget?.param?.topMargin.ifInt()
//                        if (behaviorShowHeight < minHeight) {
//                            behaviorShowHeight = minHeight
//                        }
//                    }
//                    binding.includeNav.navBtnLayout.updateLayoutParams<ViewGroup.MarginLayoutParams> { bottomMargin =
//                        (slideOffset * bottomSheet.height).toInt()
//                    }
//                    binding.mapView.updateLayoutParams<ViewGroup.MarginLayoutParams> { bottomMargin =
//                        (slideOffset * bottomSheet.height).toInt()
//                    }
//                    curHeight = behaviorShowHeight
//                    lastSlide = slideOffset
                }
            }
        })
    }

    private fun getBottomNavBarHeight(){

            var result = 0
            if (hasNavBar()) {
                var res = getResources();
                var resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
                if (resourceId > 0) {
                    result = res.getDimensionPixelSize(resourceId);
                }
            }
        Log.e("result", result.toString())
            result;

    }

    /**
     * 检查是否存在虚拟按键栏
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private fun  hasNavBar(): Boolean {
        var res = getResources()
        var resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android");
        if (resourceId != 0) {
            var hasNav = res.getBoolean(resourceId);
            var sNavBarOverride = getNavBarOverride();
            if ("1".equals(sNavBarOverride)) {
                hasNav = false;
            } else if ("0".equals(sNavBarOverride)) {
                hasNav = true;
            }
            return hasNav;
        } else {
            return !ViewConfiguration.get(this).hasPermanentMenuKey();
        }
    }

    /**
     * 判断虚拟按键栏是否重写
     */
    private fun  getNavBarOverride():String? {
        var sNavBarOverride: String? = null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            try {
                var c = Class.forName("android.os.SystemProperties");
                var m = c.getDeclaredMethod("get", String::class.java)
                m.setAccessible(true);
                sNavBarOverride = m.invoke(null, "qemu.hw.mainkeys") as String
            } catch ( e:Exception) {
            }
        }
        return sNavBarOverride;
    }

    //参考：https://blog.csdn.net/lu202032/article/details/119796731
    private fun testScreenInfo(){
        Log.e("screen", resources.displayMetrics.widthPixels.toString())
        Log.e("screen", resources.displayMetrics.heightPixels.toString())
        Log.e("screen", resources.displayMetrics.xdpi.toString())
        Log.e("screen", resources.displayMetrics.ydpi.toString())
        Log.e("screen", resources.displayMetrics.density.toString())
        Log.e("screen", resources.displayMetrics.densityDpi.toString())
        Log.e("screen", resources.displayMetrics.scaledDensity.toString())

        var height = 0;
        var resourceId = getApplicationContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            height = getApplicationContext().getResources().getDimensionPixelSize(resourceId);
        }
        Log.e("screen", height.toString())
    }

    private fun testObjectAnimator(){
        animView = findViewById(R.id.view_showhide_anim_parent)
        val objectAnimator = ObjectAnimator.ofFloat(animView, View.TRANSLATION_X, 0f, 50f)
        objectAnimator.duration = 500
        objectAnimator.start()
    }

    //参考链接：https://cloud.tencent.com/developer/article/1963836  https://developer.android.google.cn/guide/topics/graphics/prop-animation?hl=zh-cn
    //根据进度设置view样式，如宽高，左右边距，颜色(ofArgb(0xffffffff,0xffff0000,0xff0000ff))等
    //valueAnimator修改值，在回调中修改view属性达到动画效果；ObjectAnimator直接修改某一属性(ofInt中传属性：如 View.TRANSLATION_Y)
    //插值器参考：https://blog.csdn.net/pzm1993/article/details/77926373
    private fun testValueAnimator(){
        animView = findViewById(R.id.view_showhide_anim_parent)
        val valueAnimator = ValueAnimator.ofInt(0, 100)
        valueAnimator.duration = 1000
        valueAnimator.interpolator = BounceInterpolator()
        valueAnimator.addUpdateListener { animator -> // 获得每次变化后的属性值
            val currentValue = animator.animatedValue as Int

            animView?.updateLayoutParams<ViewGroup.MarginLayoutParams> { bottomMargin = currentValue }
//            (animView?.layoutParams as ViewGroup.MarginLayoutParams).updateMargins(
//                bottom = currentValue
//            )
            // 每次值变化时，将值手动赋值给对象的属性
            // 即将每次变化后的值赋给按钮的宽度，这样就实现了按钮宽度属性的动态变化
//                view.getLayoutParams().width = currentValue


            // 步骤4：刷新视图，即重新绘制，从而实现动画效果
//                view.requestLayout()
        }
//        if (endVisibleGone) {
//            valueAnimator.doOnEnd {
//                view.visibility = View.GONE
//            }
//        }
        valueAnimator.start()
    }

    private fun testRichText(){
        btn.text = Html.fromHtml("<font style='border:1px solid' color='#ff0000'><b>99</b></font>", Html.FROM_HTML_MODE_LEGACY)
    }

    private fun testImgAlpha(){
        findViewById<ImageView>(R.id.img_cloud_left).alpha = 0.5f
    }

    var animParent:FrameLayout? = null
    var animView:View? = null
    var mTransitioner = LayoutTransition()

    //使用android:animateLayoutChanges设置view显示/隐藏时的动画(默认为透明度动画),参考连接：https://blog.csdn.net/harvic880925/article/details/50985596
    private fun showHideViewWidthAnim(){
        if (animParent == null) {
            animView = findViewById(R.id.view_showhide_anim_view)

            animParent = findViewById(R.id.view_showhide_anim_parent)
            //入场动画:view在这个容器中消失时触发的动画
            val animIn = ObjectAnimator.ofFloat(null, View.TRANSLATION_Y, 360f, 0f);
            mTransitioner.setAnimator(LayoutTransition.APPEARING, animIn)

            //出场动画:view显示时的动画
            val animOut = ObjectAnimator.ofFloat(null, View.TRANSLATION_Y, 0f, 360f);
            mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut)

            mTransitioner.setDuration(500)

            animParent?.layoutTransition = mTransitioner
        }

//        if (animView.visibility == View.VISIBLE) {
            animView?.isVisible = !animView?.isVisible!!
//        }

    }

    fun showMask(){
        val view = LayoutInflater.from(this).inflate(R.layout.layout_mask, findViewById(android.R.id.content), true)

    }

    fun callPhone(){
        val dialIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:10086")) //直接拨打电话
        dialIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        application.startActivity(dialIntent)
    }

    private fun testAnim(){
        val rightAnim = AnimationUtils.loadAnimation(this, R.anim.anim_cloud_right)
        rightAnim.setAnimationListener(object :Animation.AnimationListener{
            override fun onAnimationStart(animation: Animation?) {}

            override fun onAnimationEnd(animation: Animation?) {
                val right = findViewById<View>(R.id.img_cloud_right)
                val left = findViewById<View>(R.id.img_cloud_left)
                val bg = findViewById<View>(R.id.img_cloud_bg)
                left.visibility = View.GONE
                right.visibility = View.GONE
                bg.visibility = View.GONE
            }

            override fun onAnimationRepeat(animation: Animation?) {}

        })
        findViewById<ImageView>(R.id.img_cloud_right).startAnimation(rightAnim)
        findViewById<ImageView>(R.id.img_cloud_left).startAnimation(AnimationUtils.loadAnimation(this, R.anim.anim_cloud_left))
        findViewById<View>(R.id.img_cloud_bg).startAnimation(AnimationUtils.loadAnimation(this, R.anim.anim_cloud_fade_bg))
    }

    var count = 0
    private fun testToast(){
        ToastUtils.instance.toast("hahahhaha${++count}")
    }

    var lottieView:LottieAnimationView? = null
    private fun testLottie(){
        if (lottieView == null) {
            lottieView = findViewById<LottieAnimationView>(R.id.lottie_view)
//        http://10.114.38.226:8090/files/boxmotion.zi

            //        lottieView.scaleY = resources.displayMetrics.density
//        lottieView.scaleX = resources.displayMetrics.density

//        lottieView.setAnimationFromUrl("http://10.114.38.226:8090/files/boxmotion.zip")
//        lottieView.setAnimationFromUrl("http://10.114.38.226:8090/files/boxmotion.json")
//        lottieView.maintainOriginalImageBounds = true
//        lottieView.clipToCompositionBounds = true
//        lottieView.composition?.bounds?.set(0,0,10,10)

            lottieView?.setAnimation("data.json")

//        lottieView.repeatMode =  LottieDrawable.REVERSE
//        lottieView.repeatCount =  LottieDrawable.INFINITE
            lottieView?.repeatMode =  LottieDrawable.RESTART
            lottieView?.repeatCount =  1
            lottieView?.addAnimatorListener(object : Animator.AnimatorListener {
                override fun onAnimationStart(animation: Animator) {

                }

                override fun onAnimationEnd(animation: Animator) {
                    Log.e("lottie", "onAnimationEnd...")
                }

                override fun onAnimationCancel(animation: Animator) {
                }

                override fun onAnimationRepeat(animation: Animator) {
                }
            })
//        lottieView.setAnimationFromUrl("https://assets6.lottiefiles.com/packages/lf20_Tprkoc.json")
        }

        lottieView?.playAnimation()
    }

    private fun testPoster(){
        val bgBitmap = BitmapFactory.decodeResource(resources, R.drawable.share_bg_new)
        val qrBitmap = BitmapFactory.decodeResource(resources, R.drawable.qr_img)
        val avatar = BitmapFactory.decodeResource(resources, R.drawable.img_avatar)
        val avatarLabel = BitmapFactory.decodeResource(resources, R.drawable.role_label)
        val label = BitmapFactory.decodeResource(resources, R.drawable.poster_label)
        val nick = "昵称一二三四五六七八九十"

//        val builder = PosterCreator.Builder()
//            .setDesignWidth(1500)
//            .setDesignHeight(3248)
//            .addLastPaintRect(Color.parseColor("#FF5800"), Paint.Style.FILL, 0f, RectF(125f, 2976f, 136f, 3110f))
//            .addImage(bgBitmap, Rect(0, 0, bgBitmap.width, bgBitmap.height), Rect(0, 0, 1500, 3248))
//            .addImage(qrBitmap, Rect(0, 0, qrBitmap.width, qrBitmap.height), Rect(1085,2832,  1373, 3120))
//            .addTextBean(Color.parseColor("#24292B"), dp2px(18f), Paint.Style.FILL, nick, 126f, false, 2920f, true)
//            .addTextBean(Color.parseColor("#24292B"), dp2px(14f), Paint.Style.FILL, "长按识别二维码", 179f, false, 3020f)
//            .addTextBean(Color.parseColor("#24292B"), dp2px(14f), Paint.Style.FILL, "解锁你的极氪生活", 179f, false, 3100f)
//
//        builder.getPaint().textSize = dp2px(18f)
//        val width = builder.getPaint().measureText(nick)
//        builder.addImage(label, Rect(0, 0, label.width, label.height), Rect((width + 139).toInt(), 2880,
//            (width + 271).toInt(), 2922))
//
//        val bitmap = builder.create()

        val builder = PosterCreator.Builder()
            .setDesignWidth(1125)
            .setDesignHeight(2436)
            .addImage(bgBitmap, Rect(0, 0, bgBitmap.width, bgBitmap.height), Rect(0, 0, 1125, 2028))//背景图放上面
            .addRect(Color.WHITE, Paint.Style.FILL, 0f, RectF(0f, 2027f, 1125f, 2436f))
            .addImage(qrBitmap, Rect(0, 0, qrBitmap.width, qrBitmap.height), Rect(813,2125,  1029, 2341))
            .addImage(avatar, Rect(0, 0, avatar.width, avatar.height), Rect(96,2125,168,2197))
            .addImage(avatarLabel, Rect(0, 0, avatarLabel.width, avatarLabel.height), Rect(148,2177,168,2197))
            .addTextBean(Color.parseColor("#24292B"), dp2px(14f), Paint.Style.FILL, nick, 186f, false, 2175f, true)
            .addLastPaintRect(Color.parseColor("#FF5800"), Paint.Style.FILL, 0f, RectF(99f, 2235f, 107.7f, 2333f))
            .addTextBean(Color.parseColor("#24292B"), dp2px(12f), Paint.Style.FILL, "长按识别二维码", 130f, false, 2266.5f)
            .addTextBean(Color.parseColor("#24292B"), dp2px(12f), Paint.Style.FILL, "解锁你的极氪生活", 130f, false, 2322f)

        builder.getPaint().textSize = dp2px(14f)
        val width = builder.getPaint().measureText(nick)
        builder.addImage(label, Rect(0, 0, label.width, label.height), Rect((width + 206).toInt(), 2138,
            (width + 338).toInt(), 2180))

        val bitmap = builder.create()

        findViewById<ImageView>(R.id.test_image3).setImageBitmap(bitmap)
    }
    fun dp2px(dp: Float): Float {
        val r = Resources.getSystem()
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.displayMetrics)
    }

    private fun testDialogPosition(){
        val dialog = CustomDialog(this)

//        val params = dialog.window?.attributes
//        params?.width = WindowManager.LayoutParams.MATCH_PARENT
//        dialog.window?.attributes = params
//        dialog.window?.setGravity(Gravity.BOTTOM)

        dialog.show()
    }



    private fun testStep(){
        var cursor: Cursor? = null;
        try {
            cursor = getContentResolver()
                .query(Uri.parse("content://" + "com.miui.providers.steps" + "/item"), null, "_end_time between 1659924000000 and 1660010400000", null, null);

            val steps = LinkedList<Step>()

            if (cursor?.moveToFirst() == true) {
                do {
                    //_end_time between 1659974000 and 1660006800
                    var s = Step(cursor.getInt(0), cursor.getLong(1), cursor.getLong(2),
                        cursor.getInt(3),
                        cursor.getInt(4))
                    steps.add(s)
                } while (cursor.moveToNext())

                Log.e("step","count:"+ steps.size)
            }
        } catch ( e:Exception) {
            e.printStackTrace()
//            LogX.e(TAG, SUB_TAG, getName() + "; " + e.toString());
        }

        Log.e("step", "support:" + getBoolean("support_steps_provider", false))
    }

    fun getBoolean(name: String?, defaultValue: Boolean): Boolean {
        try {
            val featureParserClass = Class.forName("miui.util.FeatureParser")
            val method = featureParserClass.getMethod(
                "getBoolean",
                String::class.java,
                Boolean::class.javaPrimitiveType
            )
            return method.invoke(null, name, defaultValue) as Boolean
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return defaultValue
    }

    private fun testVibrate(){
//        val time = 100
//        VibrateUtils.vibrateOnce(this, time.toLong())
        VibrateUtils.startVibrate(this, longArrayOf(0, 25, 50, 10))
    }

    //宽度大于控件自动省略TextView
    private fun testText(){
        findViewById<LimitLengthTextView>(R.id.limit_text).setText("你哈哈哈你哈哈啦", "美食")
    }

    private fun testShapeDrawable(view: View) {
        val gd = GradientDrawable()
        gd.setColor(Color.parseColor("#0000ff"));
        gd.setCornerRadius(8f);
        gd.setStroke(2, Color.parseColor("#ff0000"));//描边的颜色和宽度
        view.background = gd

//        gd.setGradientType(GradientDrawable.RECTANGLE);

    }

    private fun testGradient(){
        val drawable = GradientDrawable().apply {
            shape = GradientDrawable.RECTANGLE
            colors = intArrayOf(
                Color.WHITE,
                Color.parseColor("#ffffffff"),
                Color.parseColor("#f1ffffff")
//                Color.parseColor("#e5ffffff")
            )
//            setGradientCenter(0.42f, 0f)
            orientation = GradientDrawable.Orientation.TOP_BOTTOM
        }
        findViewById<ImageView>(R.id.test_image3).setImageDrawable(drawable)
    }

    private fun testDialog(v:View){
        TestDialog(this).showViewBottom(v)
    }

    private fun testWorker(){
        val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager

        val intent = Intent(applicationContext, MainActivity::class.java)
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        val pendingIntent:PendingIntent = PendingIntent.getBroadcast(applicationContext, 0, intent, FLAG_IMMUTABLE)
//        alarmManager.set(AlarmManager.RTC,System.currentTimeMillis() + 1000*20,"FLAG_IMMUTABLE",object :
//            AlarmManager.OnAlarmListener {
//            override fun onAlarm() {
//                Log.e("alarm", "OnAlarmListener.....")
//            }
//
//        }, Handler(
//            Looper.getMainLooper()));

        alarmManager.setAndAllowWhileIdle(AlarmManager.RTC, System.currentTimeMillis() + 1000*20,pendingIntent)




        val currentDate = Calendar.getInstance()
        val dueDate = Calendar.getInstance()

// 设置在大约 05:00:00 AM 执行
        dueDate.set(Calendar.HOUR_OF_DAY, 15)
        dueDate.set(Calendar.MINUTE, 17)
        dueDate.set(Calendar.SECOND, 0)

        if (dueDate.before(currentDate)) {
            dueDate.add(Calendar.HOUR_OF_DAY, 24)
        }

        val timeDiff = dueDate.timeInMillis - currentDate.timeInMillis
        val dailyWorkRequest = OneTimeWorkRequestBuilder<DailyWorker>()
            .setConstraints(Constraints.Builder().build()) .setInitialDelay(timeDiff, TimeUnit.MILLISECONDS)
            .addTag("TAG_OUTPUT").build()

        WorkManager.getInstance(this).enqueue(dailyWorkRequest)
    }

    private fun testLabels(){
        val labelsView: LabelsView = findViewById(R.id.label_view)
        val bean = TestBean("h啊哈哈")
        bean.strokeWidth = 2f
        bean.strokeColor = Color.YELLOW
        bean.bgColor = Color.BLACK
        labelsView.addLabels(arrayListOf(
            bean
            , TestBean( "h啊哈哈")
            , TestBean("t测测")
            , LabelBean("他他他")
            , LabelBean("了了")
            , LabelBean("和")
        )
        )
    }
}
val Int.dp get() = this.toFloat().dp.toInt()
val Float.dp
    get() = TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        this,
        Resources.getSystem().displayMetrics
    )
class TestBean(text: String? = null): LabelBean(text){
    var labelId: String = ""
}

class Step {
    constructor(id: Int, mBeginTime: Long, mEndTime: Long, mMode: Int, mSteps: Int) {
        this.id = id
        this.mBeginTime = mBeginTime
        this.mEndTime = mEndTime
        this.mMode = mMode
        this.mSteps = mSteps
    }

    var id = 0
     var mBeginTime: Long = 0
     var mEndTime: Long = 0
     var mMode = 0
     var mSteps = 0
}

fun MainActivity.test(){
    Log.e("main", "main test...")
    AlertDialog.Builder(this).setTitle("test").show()
}